from flask import Blueprint, request, redirect, url_for, json
from flask import Flask,abort
from component import global_station_dir, Subscriber
from flask import send_from_directory
import os
import tornado
from tornado.websocket import WebSocketHandler, WebSocketClosedError
from log import logger
from o2platform import home

api = Flask(__name__, static_url_path='/ui', root_path=global_station_dir + "/station/ui")

'''
属性flag：
a：async(异步执行)
s：summary（可显示在连线视图）
r：readonly（只读）
h：hidden（隐藏）
t：transient（临时状态，不记录到配置文件）
b：builtin（内置组件，不显示在导航栏和连线视图上）
f: frozen (固定类型，不可删除修改)
'''

'''
前端接口：
iframe页面加载时寻找doLoadValues(id, values)加载组件
调用doSaveValues(id, values)保持到后端
'''
subscriber = None

class subscribe_handler(tornado.websocket.WebSocketHandler):
    def open(self):
        logger.info("websocket open")

    def check_origin(self, origin):
        return True

    def on_close(self):
        logger.info("websocket clsoe")

    def on_message(self, message):
        global subscriber
        if subscriber is None:
            subscriber = Subscriber(self)
        else:
            subscriber.unsubscribe()
            subscriber.set_socket(self)

        data = json.loads(message)
        id = data['id'];
        logger.info(id)
        if id is None:
            return ""
        comp = home.find_comoponent(id)
        if comp is None:
            return ""
        logger.info("subscribe")
        subscriber.subscribe(comp)

@api.route('/ui/<filename>')
def ui(filename):
    logger.info(filename)
    return api.send_static_file(filename)

@api.route("/navigator",  methods=['GET'])
def navigator():
    if request.method == "GET":
        return home.navigator()

@api.route("/componentui/<id>", methods=['GET'])
def component_ui(id):
    if request.method == "GET":
        return home.component_ui(id)

@api.route("/menu/<id>", methods=['GET', 'POST'])
def get_menu(id):
    if request.method == "GET":
        return home.get_menu(id)
    if request.method == "POST":
        logger.info(request.json['name'])
        return home.post_menu(id, request.json['name'], request.json['value'])

@api.route("/devices/<id>", methods=['GET'])
def get_devices(id):
    if request.method == "GET":
        res = home.get_devices(id)
        if res is False:
            abort(404)
        return res

@api.route("/networks/<id>", methods=['GET'])
def get_networks(id):
    if request.method == "GET":
        res = home.get_networks(id)
        if res is False:
            abort(404)
        return res

@api.route("/networks/<id>", methods=['GET'])
def get_points(id):
    if request.method == "GET":
        res = home.get_points(id)
        if res is False:
            abort(404)
        return res

#: station主页加载
"""
    返回工作站树状结构的json数据
"""
@api.route("/station",  methods=['GET'])
def station():
    if request.method == "GET":
        return home.get_station_reply()

@api.route("/modules", methods=['GET'])
def modules():
    if request.method == "GET":
        m = home.get_module_list()
        return m

@api.route("/module/<name>", methods=['GET'])
def get_module(name):
    if request.method == "GET":
        m = home.get_module(name)
        if m is False:
            abort(404)
        else:
            return m
    abort(404)

@api.route("/type_filter", methods=['POST'])
def type_filter():
    if request.method == "POST":
        return home.type_filter(request.json)

@api.route("/type_filter_all", methods=['POST'])
def type_filter_all():
    if request.method == "POST":
        return home.type_filter_all(request.json)

#: 返回component
"""
    返回component的json数据
"""
@api.route("/components/<id>", methods=['GET', 'DELETE'])
def components(id):
    if request.method == "GET":
        step = request.args.get('step')
        step = int(step)
        a = home.get_component_reply(id, step)
        if a is False:
            abort(404)
        else:
            return a
    if request.method == "DELETE":
        ok = home.delete_component(id)
        if ok is False:
            abort(404)
        else:
            return ""
    abort(404)

@api.route("/component", methods=['POST'])
def component():
    if request.method == "POST":
        id = request.args.get('id')
        name = request.args.get('name')
        c_type = request.args.get('type')
        ok = home.create_component(id, name, c_type)
        if ok is False:
            abort(404)
        else:
            return ok
    abort(404)

#: actions
"""
    返回events的json数据
"""

@api.route("/actions/<id>/<text>/<text_input>", methods=['GET'])
def actions(id, text, text_input):
    if request.method == "GET":
        ok = home.get_actions_reply(id, text, text_input)
        if ok is False:
            abort(404)
        else:
            return ok
    abort(404)

@api.route("/links", methods=['GET'])
def create_link():
    if request.method == "GET":
        src_id = request.args.get('src')
        src_slot = request.args.get('srcSlot')
        tar_id = request.args.get('tar')
        tar_slot = request.args.get('tarSlot')
        ok = home.create_link(str(src_id), src_slot, str(tar_id), tar_slot)
        logger.info("create link = " + str(ok))
        if ok:
            return ""
        else:
            abort(404)

@api.route("/properties", methods=['POST'])
def properties():
    if request.method == "POST":
        home.update_properties(request.json)
        print(request.json)
        return ""
    abort(404)

@api.route("/property/<id>", methods=['POST','GET'])
def property(id):
    if request.method == "POST":
        home.update_property(id, request.json)
        return ""
    if request.method == "GET":
        logger.info(id)
        ok = home.get_propertys(id)
        if ok is False:
            abort(404)
        else:
            return ok
    abort(404)

@api.route("/link/<id>/<src_name>/<tar_name>", methods=['DELETE'])
def delete_link(id, src_name, tar_name):
    if request.method == "DELETE":
        ok = home.delete_link(id, src_name, tar_name)
        logger.info("delete link = " + str(ok))
        if ok:
            return ""
        else:
            abort(404)


#: propertysheet 页面请求
"""
    请求数据格式：
    {
        "path": "station:<station name>/xxx/xxx/point1", //表示组件在station中的路径
    }
    
    数据返回格式，表示一个组件的json数据：
    例如一个标准的Component对象
    {
        "p": {
            "name": {
                "f": "hr",
                "v": "point1"
            },
            "icon": {
                "f": "hr",
                "v": "icon:component.png"
            },
            "x": {
                "f": "hr",
                "v": 10
            },
            "y": {
                "f": "hr",
                "v": 10
            },
            "w": {
                "f": "hr",
                "v": 5
            },
        }, //properties 组件属性
        "a": {
        
        }, //actions 组件行为
        "c": {
        
        }, //components 组件child组件
        "b": {
        
        }，//bingings 组件绑定
        "i":  "<class 'web.Component'>", //组件模块+类名
    }
"""
@api.route("/propertysheet",  methods=['POST'])
def propertysheet():
    if request.method == "POST":
        pass

#: slotsheet 页面请求
"""
    请求数据格式：
    {
        "path": "station:<station name>/xxx/xxx/point1", //表示组件在station中的路径
    }
    数据返回格式，表示一个组件的json数据：
    例如一个标准的Component对象
    {
        "p": {
            "name": {
                "f": "hr",
                "v": "point1"
            },
            "icon": {
                "f": "hr",
                "v": "icon:component.png"
            },
            "x": {
                "f": "hr",
                "v": 10
            },
            "y": {
                "f": "hr",
                "v": 10
            },
            "w": {
                "f": "hr",
                "v": 5
            },
        }, //properties 组件属性
        "a": {
        
        }, //actions 组件行为
        "class":  "", //组件类名称
        "module": "", //组件所属模块名称
    }
"""
@api.route("/slotsheet",  methods=['POST'])
def slotsheet():
    if request.method == "POST":
        pass

#: wiresheet 页面请求
"""
    请求数据格式：
    {
        "path": "station:<station name>/xxx/xxx/point1", //表示组件在station中的路径
    }

    数据返回格式，表示当前所属组件的json数据（当前组件必须是Folder类）：
    {
        "c": {
            ...
        }, //components 组件child组件
        "b": {
            ...
        }，//bingings 组件绑定(表示连线逻辑，这里前端显示需区分连线发生在当前页面和非当前页面两种情况)
    }
"""
@api.route("/wiresheet",  methods=['POST'])
def wiresheet():
    if request.method == "POST":
        pass

#: view 页面请求
"""
    请求数据格式：
    {
        "path": "view:<station name>/xxx/xxx/folder1/view1", //表示view在station中的路径
    }

    数据返回格式，数据格式待定（格式需描述widget属性和widget属性与组件属性的绑定信息）：
    {
       ...
    }
"""
@api.route("/view",  methods=['POST'])
def view():
    if request.method == "POST":
        pass

#: component_event 组件事件请求
"""
    请求数据格式：
    {
        "path": "station:<station name>/xxx/xxx/point1", //表示组件在station中的路径
        "type": //事件类型
        "msg": {
        
        }, //事件消息
    }

    数据返回格式，数据格式待定：
    {
       ...
    }
"""
@api.route("/component_event",  methods=['POST'])
def component_event():
    if request.method == "POST":
        pass

#: view_event view事件请求
"""
    请求数据格式：
    {
        "path": "view:<station name>/xxx/xxx/folder1/view1", //表示view在station中的路径
        "type": //事件类型
        "msg": {

        }, //事件消息
    }

    数据返回格式，数据格式待定：
    {
       ...
    }
"""
@api.route("/view_event",  methods=['POST'])
def view_event(count):
    if request.method == "POST":
        pass

